import { Injectable, PipeTransform, ArgumentMetadata, HttpStatus, } from "@nestjs/common";
import { ApiException } from "../exception/api.exception";
import { plainToClass } from "class-transform";
import { validate } from "class-validator";

@Injectable()
export class ApiParamsValidationPipe implements PipeTransform{
    async transform(value:any,metadata:ArgumentMetadata){
        const { metaType } = metadata;
        //如果参数是普通的js对象则不验证
        if(!metaType || !this.toValidate(metaType)) return value;

        //通过元数据和对象实例，构建原有类型
        const object = plainToClass(metaType,value);
        const errors = await validate(object);

        if(errors.length){
            //获取第一个没有通过验证的错误对象
            let error = errors.shift();
            let constrains = error.constrains;
            let contexts = error.contexts;

            //将未通过验证的字段的错误信息和状态码，以ApiException的形式抛给我们的2全局异常过滤器
            for(let key in constrains){
                throw new ApiException(
                    constrains[key],
                    contexts[key].errorCode,
                    HttpStatus.BAD_REQUEST,
                )
            }
        }

        return object;
    }

    private toValidate(metaType:any):boolean{
        const types = [String,Boolean,Number,Array,Object];

        return !types.find(type => metaType ===type);
    }

}